package com.quickcode.example.singleton;

import com.quickcode.annotation.UnSafe;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程不安全原因：可能会存在cpu指令重排，如流程：
 * 1、给对象instance分配存储空间
 * 2、实例化instance对象，执行其构造方法中的逻辑
 * 3、将instance对象的引用指向实例化出来的对象
 * 当发生cpu指令重排时，可能会出现第3步先于第2步执行，最终导致另外的线程在使用instance对象时对象构造方法中的逻辑还未执行导致异常
 * Created by 张波 on 2019/10/23.
 */
@UnSafe
@Slf4j
public class SingletonExample3 {

    private static SingletonExample3 instance = null;

    private SingletonExample3() {
        log.error("调用了构造方法创建了对象");
    }

    public static SingletonExample3 getInstance() {
        if (instance == null) {
            synchronized (SingletonExample3.class) {
                if (instance == null) {
                    instance = new SingletonExample3();
                }
            }

        }
        return instance;
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 100; ++i) {
            executorService.execute(() -> {
                if(null == SingletonExample3.getInstance()) {
                    log.error("我取了个null值");
                }
            });
        }
        executorService.shutdown();
    }

}
